﻿using Autofac;
using KJSyncXP.Access.Context;
using KJSyncXP.Extensions;
using KJSyncXP.SQLite.Context;
using log4net.Config;
using System;
using System.Configuration;
using System.IO;
using System.Windows;
using log4net;
using KJSyncXP.Sync.Services;
using KJSyncXP.Oracle.Context;
using KJSyncXP.Services;
using KJSyncXP.ViewModels;
using KJSyncXP.Views;
using KJSync.Access.Models;
// 引入纯WPF托盘库命名空间
using Hardcodet.Wpf.TaskbarNotification;
using System.Windows.Input;
using FreeRedis;

namespace KJSyncXP
{
    /// <summary>
    /// App.xaml 的交互逻辑（集成DI+托盘功能）
    /// </summary>
    public partial class App : Application
    {
        public static IContainer _container;
        private static readonly ILog _log = LogManager.GetLogger(typeof(App));
        private TaskbarIcon _trayIcon; // 纯WPF托盘图标（无WinForms依赖）
        private MainWindow _mainWindow; // 主窗口引用（用于托盘操作）

        
        private FileChangeWatcher _fileChangeWatcher;// 保存监听器实例，用于退出时释放

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            RegisterDI(); // 原有DI注册逻辑
            InitTrayIcon(); // 初始化托盘（新增）

            // 解析主窗口并绑定关闭事件（拦截关闭行为）
            var scope = _container.BeginLifetimeScope();
            _mainWindow = scope.Resolve<MainWindow>();
            _mainWindow.Closing += MainWindow_Closing; // 绑定关闭事件（新增）

            _fileChangeWatcher = scope.Resolve<FileChangeWatcher>();

            _mainWindow.WindowState = WindowState.Maximized;
            _mainWindow.Show();
        }

        #region 托盘功能相关逻辑
        /// <summary>
        /// 初始化纯WPF托盘图标（图标、交互、菜单）
        /// </summary>
        private void InitTrayIcon()
        {
            try
            {
                // 创建托盘图
                _trayIcon = new TaskbarIcon
                {
                    // 图标路径："pack://application:,,,/" + 项目中图标文件的相对路径
                    IconSource= new System.Windows.Media.Imaging.BitmapImage(
                        new Uri("pack://application:,,,/KJSyncXP;component/Resources/TrayIcon.ico")),
                    ToolTipText = "KJSyncXP 同步工具", // 鼠标悬浮提示文字
                    // = true // 显示托盘图标
                };

                // 2. 托盘双击事件：恢复主窗口（绑定命令）
                _trayIcon.DoubleClickCommand = new RelayCommand(() =>
                {
                    if (_mainWindow != null)
                    {
                        _mainWindow.WindowState = WindowState.Normal;
                        _mainWindow.ShowInTaskbar = true;
                        _mainWindow.Activate(); // 激活窗口到前台
                    }
                });

                // 3. 托盘右键菜单：退出应用（彻底关闭，终止定时任务）
                var exitMenuItem = new System.Windows.Controls.MenuItem
                {
                    Header = "退出应用"
                };
                exitMenuItem.Click += (s, args) =>
                {
                    /*_trayIcon.Dispose(); // 释放托盘资源
                    Shutdown(); // 关闭整个应用


                    if (confirm == MessageBoxResult.Yes)
                    {
                        // 1. 仅释放“非托管资源”（必须手动释放，否则会残留）
                        _fileChangeWatcher?.StopWatching(); // 停止文件监听（释放文件句柄）
                        _trayIcon?.Dispose(); // 释放托盘图标（避免任务栏残留）

                        // 2. 强制终止当前进程（所有线程、后台任务、托管资源全清）
                        Environment.Exit(0); // 0 表示正常退出代码
                    }*/

                    var confirm = MessageBox.Show(
                        "确定退出？退出后定时任务将停止",
                        "退出确认",
                        MessageBoxButton.YesNo,
                        MessageBoxImage.Warning);

                    if (confirm == MessageBoxResult.Yes)
                    {
                        // 1. 仅释放“非托管资源”（必须手动释放，否则会残留）
                        _fileChangeWatcher?.StopWatching(); // 停止文件监听（释放文件句柄）
                        _trayIcon?.Dispose(); // 释放托盘图标（避免任务栏残留）

                        // 2. 强制终止当前进程（所有线程、后台任务、托管资源全清）
                        Environment.Exit(0); // 0 表示正常退出代码
                    }
                };

                // 绑定右键菜单到托盘
                _trayIcon.ContextMenu = new System.Windows.Controls.ContextMenu
                {
                    Items = { exitMenuItem }
                };
            }
            catch (Exception ex)
            {
                _log.Error("纯WPF托盘初始化失败", ex);
                MessageBox.Show($"托盘功能初始化错误：{ex.Message}", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        /// <summary>
        /// 拦截主窗口关闭事件：替换为“最小化到托盘”
        /// </summary>
        private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // 取消默认关闭行为（阻止窗口销毁，保留定时任务）
            e.Cancel = true;

            // 最小化窗口并隐藏任务栏图标（只在托盘显示）
            if (_mainWindow != null)
            {
                _mainWindow.WindowState = WindowState.Minimized;
                _mainWindow.ShowInTaskbar = false;
                _log.Info("应用已最小化到托盘，定时任务继续运行");
            }
        }

        /// <summary>
        /// 简易ICommand实现（用于托盘双击命令绑定，无MVVM框架时可用）
        /// </summary>
        private class RelayCommand : ICommand
        {
            private readonly Action _executeAction;
            public RelayCommand(Action executeAction) => _executeAction = executeAction;

            public bool CanExecute(object parameter) => true;
            public void Execute(object parameter) => _executeAction?.Invoke();
            public event EventHandler CanExecuteChanged;
        }
        #endregion

        #region 依赖注入（DI）注册逻辑
        private void RegisterDI()
        {
            try
            {
                // log4net 配置
                string log4netConfigPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config");
                FileInfo configFile = new FileInfo(log4netConfigPath);
                if (configFile.Exists)
                {
                    XmlConfigurator.Configure(configFile);
                }
                else
                {
                    MessageBox.Show("log4net.config 不存在，日志可能无法正常记录！", "配置错误",
                        MessageBoxButton.OK, MessageBoxImage.Warning);
                }

                // 注册配置类 AppConfig（单例）
                var config = AppConfigReader.ReadConfig();
                if (config == null)
                {
                    throw new InvalidOperationException("无法读取配置文件，请检查AppConfig.json是否存在且格式正确");
                }

                // 创建容器构建器
                var builder = new ContainerBuilder();

                // 注册日志（单例）
                builder.RegisterInstance(LogManager.GetLogger(typeof(App)))
                       .As<ILog>()
                       .SingleInstance();

                // 注册配置（单例）
                builder.RegisterInstance(config)
                       .As<AppConfig>()
                       .SingleInstance();

                // 注册 AccessDbContext（每次作用域一个实例）
                builder.Register(c =>
                {
                    var appConfig = c.Resolve<AppConfig>();
                    if (string.IsNullOrEmpty(appConfig.AccessConnectionString))
                    {
                        throw new ConfigurationErrorsException("AppConfig 中未配置 AccessConnectionString");
                    }
                    return new AccessDbContext(appConfig.AccessConnectionString);
                })
                .AsSelf()
                .InstancePerLifetimeScope();

                // 注册 AccessDbContext2 有两个数据库
                builder.Register(c =>
                {
                    var appConfig = c.Resolve<AppConfig>();
                    if (string.IsNullOrEmpty(appConfig.AccessConnectionString2))
                    {
                        throw new ConfigurationErrorsException("AppConfig 中未配置 AccessConnectionString2");
                    }
                    return new AccessDbContext2(appConfig.AccessConnectionString2);
                })
                .AsSelf()
                .InstancePerLifetimeScope();

                // 注册 SqliteDbContext（每次作用域一个实例）
                builder.Register(c =>
                {
                    var appConfig = c.Resolve<AppConfig>();
                    if (string.IsNullOrEmpty(appConfig.SqliteConnectionString))
                    {
                        throw new ConfigurationErrorsException("AppConfig 中未配置 SqliteConnectionString");
                    }
                    return new SqliteDbContext(appConfig.SqliteConnectionString);
                })
                .AsSelf()
                .InstancePerLifetimeScope();

                // 注册 OracleDbContext（每次作用域一个实例）
                builder.Register(c =>
                {
                    var appConfig = c.Resolve<AppConfig>();
                    if (string.IsNullOrEmpty(appConfig.OracleMesConnectionString))
                    {
                        throw new ConfigurationErrorsException("AppConfig 中未配置 OracleMesConnectionString");
                    }
                    return new OracleDbContext(appConfig.OracleMesConnectionString);
                })
                .AsSelf()
                .InstancePerLifetimeScope();

                // 注册 IdFileManager
                builder.RegisterType<IdFileManager>().AsSelf().InstancePerLifetimeScope();
               

                // 注册同步服务（每次作用域一个实例）
                builder.RegisterType<AccessSqliteSyncService>().AsSelf().InstancePerLifetimeScope();
                builder.RegisterType<OracleSqliteSyncService>().AsSelf().InstancePerLifetimeScope();
                builder.RegisterType<SqliteToFileSyncService>().AsSelf().InstancePerLifetimeScope();
                builder.RegisterType<AuthorizationService>().AsSelf().InstancePerLifetimeScope();


                builder.RegisterType<FileChangeWatcher>().AsSelf().SingleInstance();

                // 注册实体类、窗口、ViewModel
                builder.RegisterType<Bas001>().AsSelf().InstancePerDependency();

                builder.RegisterType<MainWindow>().AsSelf();
                builder.RegisterType<Standard>().AsSelf();
                builder.RegisterType<ResultRetrial>().AsSelf();
                builder.RegisterType<Changelog>().AsSelf();
                builder.RegisterType<CheckPoint>().AsSelf();
                builder.RegisterType<SetSettings>().AsSelf();
                builder.RegisterType<CheckResult>().AsSelf();
                builder.RegisterType<UserPage>().AsSelf();

                builder.RegisterType<MainWindowViewModel>().AsSelf();
                builder.RegisterType<StandardViewModel>().AsSelf();
                builder.RegisterType<SetSettingsViewModel>().AsSelf();
                builder.RegisterType<ShiftItemViewModel>().AsSelf();
                builder.RegisterType<CheckPointViewModel>().AsSelf();
                builder.RegisterType<CheckResultViewModel>().AsSelf();
                builder.RegisterType<LoginViewModel>().AsSelf();
                builder.RegisterType<StandardSelectViewModel>().AsSelf();
                builder.RegisterType<UserManagerVM>().AsSelf().SingleInstance();
                builder.RegisterType<AuthorizationVM>().AsSelf();
                



                // 构建DI容器
                _container = builder.Build();
                if (_container == null)
                {
                    throw new InvalidOperationException("依赖注入容器构建失败");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"依赖注入注册失败：{ex.Message}", "启动错误", MessageBoxButton.OK, MessageBoxImage.Error);
                Shutdown();
            }
        }
        #endregion

        /// <summary>
        /// 应用退出时释放托盘资源（避免内存泄漏）
        /// </summary>
        protected override void OnExit(ExitEventArgs e)
        {
            _fileChangeWatcher?.StopWatching(); // 应用退出时停止监听，释放资源
            _trayIcon?.Dispose(); // 释放纯WPF托盘资源
            base.OnExit(e);
        }
    }
}